package com.distribute.distributelock.common.lock;

import redis.clients.jedis.Jedis;

import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;

/**
 * @description:
 * @author: 刘帅
 * @time: 2020/5/14 12:31
 * 存在问题 解锁不具备原子性
 */
public class LockCase3 extends RedisLock{

    public LockCase3(Jedis jedis, String lockKey) {
        super(jedis, lockKey);
    }

    // 抽象类RedisLock增加lockValue字段，lockValue字段的默认值为UUID随机值假设当前线程ID。
    public LockCase3(Jedis jedis, String lockKey, String lockValue) {
        super(jedis, lockKey, UUID.randomUUID().toString() + Thread.currentThread().getId());
    }

    @Override
    public void sleepBySecond(int second) {
        super.sleepBySecond(second);
    }

    @Override
    public void lock() {
        //自旋锁等待锁释放， 适用于任务时间短，否则大量的 自选浪费CPU
        while (true) {
            String result = jedis.set(lockKey, lockValue, "NX", "EX", 3000);
            if ("OK".equals(result)) {
//                System.out.println(Thread.currentThread().getId() + "加锁成功");
                break;
            }
        }
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        super.lockInterruptibly();
    }

    @Override
    public boolean tryLock() {
        return super.tryLock();
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return super.tryLock(time, unit);
    }

    /**
     *@描述
     *@创建人 liushuai
     *@创建时间 2020/5/14 16:10
        * @param null
     *@返回值
     * 此处释放锁不具备原子性
     * 释放所分为三个步骤
     * 1. 获取值
     * 2. 检查是否与 requestID （lockValue）相等
     * 3. 如果相等则删除锁
     * i++ 问题 详见 问题.md
     */
    @Override
    public void unlock() {
         //方法1
        String lockValue = jedis.get(lockKey);
        if (this.lockValue.equals(lockValue)) {
            jedis.del(lockKey);
        }

        // 方法2 使用lua脚本进行原子删除操作
//        String checkAndDelScript = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
//                "return redis.call('del', KEYS[1]) " +
//                "else " +
//                "return 0 " +
//                "end";
//        jedis.eval(checkAndDelScript, 1, lockKey, lockValue);
    }

    /**
     *@描述
     *@创建人 liushuai
     *@创建时间 2020/5/14 16:09
        * @param null
     *@返回值
     */
    @Override
    public Condition newCondition() {
        return super.newCondition();
    }
}
